package com.sun.showcase.strategy.limit;

import java.util.concurrent.TimeUnit;

import org.redisson.api.RAtomicLong;
import org.redisson.api.RLock;

import com.sun.showcase.config.redisson.RedissLockUtil;

/**
 * 基于redisson的分布式限流
 * @author SUN
 *
 */
public class RedissonRateLimitStrategy implements RateLimitStrategy {
	/**
	 * 锁时间 ， 超时自动释放
	 */
	private long lockTime = 5000;
	/**
	 * 限流时间，即在 limitTime时间内【累计】允许多大的流量通过
	 */
	private long limitTime = 1000;

	public RedissonRateLimitStrategy(long lockTime, long limitTime) {
		super();
		this.lockTime = lockTime;
		this.limitTime = limitTime;
	}

	@Override
	public boolean doLimit(String key,int rate) {
		boolean canAccess = true;
		RLock lock = RedissLockUtil.getReadWriteLock("lock:"+key).writeLock();
		lock.lock(lockTime, TimeUnit.MILLISECONDS);
		RAtomicLong callTimes = RedissLockUtil.getAtomicLong(key);
		if (!callTimes.isExists()) {
			callTimes.set(0L);
			callTimes.expire(limitTime, TimeUnit.MILLISECONDS);
		}
		if (callTimes.get() + 1 > rate) {
			canAccess = false;
		}
		if (canAccess) {
			// 可以访问，访问次数增加
			callTimes.incrementAndGet();
		}
		lock.unlock();
		return canAccess;
	}

	public long getLockTime() {
		return lockTime;
	}

	public void setLockTime(long lockTime) {
		this.lockTime = lockTime;
	}

	public long getLimitTime() {
		return limitTime;
	}

	public void setLimitTime(long limitTime) {
		this.limitTime = limitTime;
	}

}
